package models

import (
	"github.com/astaxie/beego"
	"errors"
	"gopkg.in/gomail.v2"
	"crypto/tls"
	"strings"
	"github.com/astaxie/beego/orm"
	"mailsrv/utils"
	"strconv"
)

type Mailer struct {
	Id              int64 `json:"id"`
	App_id string `json:"app_id"`
	App_name string `json:"app_name"`
	Title string `json:"title"`
	To string `json:"to"`
	Cc string `json:"cc"`
	Bcc string `json:"bcc"`
	Content string `json:"content"`
	Dostatus int `json:"dostatus"`
	BaseTable
}
type MailQueryParam struct {
	TitleLike 	string //模糊查询
	App_id 		string //精确查询
	Dostatus    string //精确查询
}
type ApiSign struct{
	MailBody
	Sign string  `json:"sign"`
	Timestamp int64 `json:"timestamp"`
}

type MailBody struct {
	Id int64
	App_id string `json:"appid"`
	Title string `json:"title"`
	To []string `json:"to"`
	Cc []string `json:"cc"`
	Bcc []string `json:"bcc"`
	Content string `json:"content"`
}

func (a *Mailer) TableName() string {
	return TableMap["mailer"]
}


func (sign *ApiSign) CheckSign() error{
	appModel := Apps{}
	appInfo,_ := appModel.GetOneByAppid(sign.App_id)

	if appInfo == nil{
		return errors.New("appid is err")
	}
	timePlus := utils.GoAbs(utils.GetTimesInt() - sign.Timestamp)

	if timePlus > 300 {
		return errors.New("request is expired")
	}

	beforeSign := sign.App_id+strconv.FormatInt(sign.Timestamp,10)+sign.Title+appInfo.Appkey
	afterSign := utils.String2md5(beforeSign)

	if afterSign != sign.Sign {
		return errors.New("sign is err")
	}

	return nil
}

//获取分页数据
func (mailer *Mailer) PageList(params *MailQueryParam ,pagenum int) ([]*Mailer, int64) {
	pagesize, _ := beego.AppConfig.Int("PageSize")
	builderSql, _ := orm.NewQueryBuilder("mysql")
	builderSql = builderSql.Select("`id`","`app_id`","`app_name`","`to`" ,"`cc`","`title`","`dostatus`","`created_at`").From(mailer.TableName())
	bindParam := []string{}

	o := orm.NewOrm()
	qs := o.QueryTable(mailer.TableName())

	var isWhere = 0;
	if params.App_id != ""{
		bindParam = append(bindParam, params.App_id)
		builderSql = builderSql.Where("app_id = ?") //params.App_id
		qs = qs.Filter("app_id", params.App_id)
		isWhere = 1
	}
	if params.Dostatus != ""{
		bindParam = append(bindParam, params.Dostatus)
		if isWhere == 1 {
			builderSql = builderSql.And("dostatus = ?" )//params.Dostatus
		}else{
			builderSql = builderSql.Where("dostatus = ?" )//params.Dostatus
		}
		qs = qs.Filter("dostatus", params.Dostatus)
		isWhere = 1
	}
	if params.TitleLike != ""{
		bindParam = append(bindParam, params.TitleLike)

		if isWhere == 1 {
			builderSql = builderSql.And("title like %?%") //, params.TitleLike
		}else{
			builderSql = builderSql.Where("title like %?%") //, params.TitleLike
		}
		qs = qs.Filter("title__icontains", params.TitleLike)
	}

	data := make([]*Mailer, 0)
	limit := (pagenum-1)*pagesize
	builderSql = builderSql.OrderBy("id").Desc().Limit(pagesize).Offset(limit)
	pageSql := builderSql.String()
	query := orm.NewOrm()

	total, _ := qs.Count()
	query.Raw(pageSql, bindParam).QueryRows(&data)
	return data, total
}

//通过ID获取记录
func (mailer *Mailer) GetOne(id int)  (*Mailer, error){
	o := orm.NewOrm()
	where := Mailer{}
	qs := o.QueryTable(where.TableName())
	err := qs.Filter("id", id).One(&where)

	if err != nil {
		return nil, err
	}
	return &where, nil
}

/*
发送一个简单的邮件
 */
 func (mailbb *MailBody) SendOne() (int64, error){
	 if mailbb.Title == "" {
	 	return 0, errors.New("not found title")
	 }
	 if len(mailbb.To) == 0 {
		 return 0, errors.New("not found to user")
	 }
	 if mailbb.Content == "" {
		 return 0, errors.New("not found content")
	 }
	 appModel := Apps{}
	 appInfo,_ := appModel.GetOneByAppid(mailbb.App_id)


	 mailer := Mailer{
	 	Title:mailbb.Title,
	 	App_id:appInfo.Appid,
	 	App_name:appInfo.Name,
	 	To:strings.Join(mailbb.To, ";"),
	 	Cc:strings.Join(mailbb.Cc, ";"),
	 	Bcc:strings.Join(mailbb.Bcc, ";"),
	 	Content:mailbb.Content,
	 	Dostatus:0,
	 	BaseTable:BaseTable{
			utils.GetNowTime(),
			utils.GetNowTime(),
		},
	 }
	 o := orm.NewOrm()
	 // 插入数据
	 id, err := o.Insert(&mailer)
	 if err != nil{
		 panic(err)
	 }

	 mailer.Id = id

	 return id, nil
 }





func (mailbb *MailBody)SingleMailTo() error{

	//获取发送邮箱配置
	host := strings.TrimSpace(beego.AppConfig.String("mail_host"))
	port,_ := beego.AppConfig.Int("mail_port")
	from := strings.TrimSpace(beego.AppConfig.String("mail_from"))
	account := strings.TrimSpace(beego.AppConfig.String("mail_account"))
	password := strings.TrimSpace(beego.AppConfig.String("mail_password"))
	secret := strings.TrimSpace(beego.AppConfig.String("mail_secure"))

	gomailReps := gomail.NewMessage()
	gomailReps.SetAddressHeader("From", account, from)
	gomailReps.SetHeader("To", mailbb.To...)
	if len(mailbb.Cc) > 0{
		gomailReps.SetHeader("Cc", mailbb.Cc...)
	}
	if len(mailbb.Bcc) > 0{
		gomailReps.SetHeader("Bcc", mailbb.Bcc...)
	}
	gomailReps.SetHeader("Subject", mailbb.Title)
	gomailReps.SetBody("text/html", mailbb.Content)

	d := gomail.NewDialer(host, port, account, password)
	if secret == "tls"{
		d.TLSConfig = &tls.Config{InsecureSkipVerify: true}
	}else if secret == "ssl"{
		d.SSL = true
	}


	mailer := &Mailer{
		Id:mailbb.Id,
		BaseTable:BaseTable{
			Updated_at:utils.GetNowTime(),
			},
	}

	beego.Notice(mailer)
	o := orm.NewOrm()
	if err := d.DialAndSend(gomailReps); err != nil {
		mailer.Dostatus = -1
		o.Update(mailer, "Id", "Dostatus", "Updated_at")
	 	return err
	}

	mailer.Dostatus = 1
	o.Update(mailer, "Id", "Dostatus", "Updated_at")
	return nil
}
